home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 June: Reference Library / Dev.CD Jun 94.toast / Periodicals / develop / develop Issue 15 / develop 15 code / Symmetry & Tiles / Tiler Code / Group2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-13  |  5.7 KB  |  213 lines  |  [TEXT/KAHL]

  1. #include     <graphics libraries.h>
  2. #include     <graphics toolbox.h>
  3. #include     "SymmetryUtils.h"
  4. #include    "TileConstants.h"
  5. #include    "TileProtos.h"
  6. #include     "Group2.h"
  7.  
  8. extern gxPatternRecord    gPattern;
  9. extern gxShape            gTileShape;
  10. extern dragger            gDragger;        // A record containing a manipulable contour & associated stuff
  11. extern gxShape            gOpShapes[];    // Group of shapes to show the
  12.                                         // symmetry operations
  13.  
  14. extern Boolean            gContRedraw, gKeepClosed;
  15.  
  16. // Prototype of a function in utils.c we use
  17. long     labs(long i);
  18.  
  19.  
  20. ///////////////////////////////////////////////////////////////////////////////////
  21. //    Group p2
  22.  
  23. // Test for a hit on an op shape, tracking the drag and returning true
  24. // if one was hit, false otherwise
  25. Boolean    p2_OpShapeHit(gxPoint *clickPt)
  26. {
  27.     gxHitTestInfo    hitStats;
  28.     gxShape            hitShape, oldShape;
  29.     gxTransform        xForm;
  30.     long            shapeNum;
  31.     
  32.     // Don't check shpe 0
  33.     for(shapeNum = 1; shapeNum < 3; shapeNum++)
  34.     {
  35.         hitShape = gOpShapes[shapeNum];
  36.         xForm = GXGetShapeTransform(hitShape);
  37.         
  38.         // Test for a hit on the startCap
  39.         GXIgnoreGraphicsNotice(attributes_already_set);
  40.         GXSetTransformHitTest(xForm, gxAnyPart, kHitTolerance);
  41.         GXPopGraphicsNotice();
  42.             
  43.         // If shape was hit, we're done looking
  44.         if(GXHitTestShape(hitShape, clickPt, &hitStats))
  45.             break;
  46.     }
  47.     
  48.     // If a shape was hit, track it
  49.     if(shapeNum < 3)
  50.     {
  51.         gxPoint        anchor, pt, lastPt = *clickPt;
  52.         
  53.         hitShape = gOpShapes[shapeNum];
  54.         
  55.         // Get the "anchor" point (shape 0)
  56.         GXGetPoint(gOpShapes[0], &anchor);
  57.         
  58.         // Create a shape for saving the old position
  59.         if(!gContRedraw)
  60.             oldShape = GXCopyToShape(nil, hitShape);
  61.  
  62.         // Follow the drag around
  63.         while(StillDown())
  64.         {
  65.             // Get the new mouse position and if it's different,
  66.             // adjust the dragged shape
  67.             GXGetViewPortMouse(0, &pt);
  68.             if(pt.x != lastPt.x || pt.y != lastPt.y)
  69.             {
  70.                 // Save old shape so we can erase and draw in rapid succession
  71.                 if(!gContRedraw)
  72.                 {
  73.                     GXCopyToShape(oldShape, hitShape);
  74.                     
  75.                     // If constraints are on, erase the dragger before.
  76.                     if(gKeepClosed)
  77.                         EraseAShape(gDragger.snake1);
  78.                 }
  79.                 
  80.                 // Move it
  81.                 p2_DragOpShape(hitShape, &pt, &anchor);
  82.                 
  83.                 if(gContRedraw)
  84.                 {
  85.                     // Reset pattern and draw it right now
  86.                     p2_ChangeLattice();
  87.                       OffToScreen();
  88.                 }
  89.                   else
  90.                   {
  91.                     // Erase and draw
  92.                     EraseAShape(oldShape);
  93.                     GXDrawShape(hitShape);
  94.                     
  95.                     // If constraints are on, draw the dragger too.
  96.                     if(gKeepClosed)
  97.                         GXDrawShape(gDragger.snake1);
  98.                   }
  99.               }
  100.             lastPt = pt;
  101.         }
  102.         if(!gContRedraw)
  103.         {
  104.             p2_ChangeLattice(); // Update the pattern
  105.             GXDisposeShape(oldShape);
  106.         }
  107.         return true;
  108.     }
  109.     else    // nothing hit
  110.         return false;
  111. }
  112.  
  113. // Moves the op shape as appropriate
  114. void    p2_DragOpShape(gxShape dragShape, gxPoint *clickPt, gxPoint *anchor)
  115. {
  116.     fixed    xd = clickPt->x - anchor->x, yd = clickPt->y - anchor->y,
  117.             lxd = labs(clickPt->x - anchor->x), lyd = labs(clickPt->y - anchor->y);
  118.     gxPoint    temp;
  119.     
  120.     // If the point is in bounds, just use it
  121.     if(lxd < kMaxDistance && lyd < kMaxDistance &&
  122.         (lyd > kMinDistance || lxd > kMinDistance) )
  123.     {
  124.         GXSetPoint(dragShape, clickPt);
  125.     }
  126.     else  // Constrain it to the bounds
  127.     {
  128.         temp = *clickPt;
  129.         if( lxd > kMaxDistance )
  130.             temp.x = anchor->x + ( (xd < 0) ? -kMaxDistance : kMaxDistance);
  131.         else if( lxd < kMinDistance )
  132.             temp.x = anchor->x + ( (xd < 0) ? -kMinDistance : kMinDistance);
  133.         
  134.         if( lyd > kMaxDistance )
  135.             temp.y = anchor->y + ( (yd < 0) ? -kMaxDistance : kMaxDistance);
  136.         else if( lyd < kMinDistance )
  137.             temp.y = anchor->y + ( (yd < 0) ? -kMinDistance : kMinDistance);
  138.         
  139.         GXSetPoint(dragShape, &temp);
  140.     }
  141. }
  142.  
  143. // Called either to set the default shapes when resetting the tile, or when 
  144. // the symmetry has changed, to convert one lattice type to another.
  145. // Currently only resets to default
  146. void     p2_RemakeOpShapes(Boolean useDefaults)
  147. {
  148.     gxShape    tempShape;
  149.     
  150.     if(true /* useDefaults */)
  151.     {
  152.         tempShape = MakeOpShape(roto2Op);
  153.         GXMoveShape(tempShape, kStartingOffset, kStartingOffset);
  154.         gOpShapes[0] = GXCopyToShape(nil, tempShape);
  155.         GXMoveShape(tempShape, kStartingGridSize, 0);
  156.         gOpShapes[1] = GXCopyToShape(nil, tempShape);
  157.         GXMoveShape(tempShape, -kStartingGridSize, kStartingGridSize);
  158.         gOpShapes[2] = tempShape;
  159.     }
  160. }
  161.  
  162. // Set the dragger to the default shape.
  163. void    p2_SetDefaultDragger(gxShape snake)
  164. {
  165.     long        dragPoly[] = {    1,    // number of contours
  166.                                 4,    // number of points
  167.                                 0, kStartingGridSize,
  168.                                 0, 0,
  169.                                 kStartingGridSize, 0,
  170.                                 kStartingGridSize, kStartingGridSize  };
  171.                 
  172.  
  173.     // make the starting drag shape
  174.     GXSetPolygons(snake, (gxPolygons *) dragPoly);
  175.     GXMoveShape(snake, kStartingOffset, kStartingOffset);
  176. }
  177.  
  178. // Reset the pattern vectors according to the positions of the op shapes
  179. void    p2_ChangeLattice(void)
  180. {
  181.     gxPoint        start, end1, end2;
  182.  
  183.     // Adjust points to define the true unit cell.
  184.     GXGetPoint(gOpShapes[0], &start);
  185.     GXGetPoint(gOpShapes[1], &end1);
  186.     GXGetPoint(gOpShapes[2], &end2);
  187.     gPattern.u.x = 2 *(end1.x - start.x);
  188.     gPattern.u.y = 2 * (end1.y - start.y);
  189.     gPattern.v.x = 2 * (end2.x - start.x);
  190.     gPattern.v.y = 2 * (end2.y - start.y);
  191.     
  192.     // Now remake the pattern according to the new lattice and draw it offscreen
  193.     RemakeTile();
  194. }
  195.  
  196. // Repeat the tile geometry as necessary to build up the full unit cell
  197. void    p2_BuildCellShape(gxShape snake)
  198. {
  199.     gxShape    tempShape;
  200.     gxPoint    origin, ctr;
  201.     
  202.     // Get the point to rotate around: center of the unit cell
  203.     GXGetPoint(gOpShapes[0], &origin);
  204.     ctr.x = origin.x + (gPattern.u.x + gPattern.v.x) / 2;
  205.     ctr.y = origin.y + (gPattern.u.y + gPattern.v.y) / 2;
  206.     
  207.     // Copy the shape, rotate it, and add it back in
  208.     tempShape = GXCopyToShape(nil, gTileShape);
  209.     GXRotateShape(tempShape, ff(180), ctr.x, ctr.y);
  210.     GXSetShapeParts(gTileShape, 0, gxSelectToEnd, tempShape, gxBreakLeftEdit);
  211.     GXDisposeShape(tempShape);
  212. }
  213.